package com.cqs.learning.spring.cloud.producer.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 1. 限流
 * 2. 熔断
 *
 * @author lixw
 * @date created in 21:26 2020/4/5
 */
@Log4j2
@Service
public class DegradeServiceImpl {

    private final AtomicInteger flowCnt = new AtomicInteger();
    private final AtomicInteger exceptionCnt = new AtomicInteger();

    public int flow() {
        int cnt = flowCnt.addAndGet(1);
        log.info("flow方法被执行" + cnt);
        return cnt;
    }

    /**
     * 用于熔断
     *
     * @param millSeconds
     * @return
     */
    @SentinelResource(value = "fuseResource", blockHandler = "fuseBlockHandler", fallback = "fuseFallback")
    public Integer errorReq(int millSeconds) {
        int cnt = 0;
        try {
            TimeUnit.MILLISECONDS.sleep(millSeconds);
        } catch (InterruptedException e) {
        } finally {
            cnt = exceptionCnt.addAndGet(1);
        }
        throw new RuntimeException("异常次数:" + cnt);
    }

    /***
     * 熔断的时候执行 -- 签名必须和errorReq保持一直
     * 或者抛出异常逻辑
     * @param millSeconds
     * @param throwable
     * @return
     */
    public Integer fuseFallback(int millSeconds, Throwable throwable) {
        log.warn(throwable.getClass() + " 执行fuseFallbackk:" + millSeconds);
        return -1;
    }

    public Integer cntFallback(Throwable throwable) {
        log.warn(throwable.getClass() + " 执行cntFallback:");
        return -2;
    }

    /**
     * 异常处理
     *
     * @param num
     * @param ex
     * @return
     */
    public static Integer fuseBlockHandler(int num, Throwable ex) {
        log.warn("执行blockHandler:" + num + "\t" + ex.getMessage());
        return -3;
    }

    /**
     * 异常处理
     *
     * @param ex
     * @return
     */
    public static Integer cntBlockHandler(Throwable ex) {
        log.warn("执行cntBlockHandlerr:" + "\t" + ex.getMessage());
        return -4;
    }

}
